<!DOCTYPE html>
<html lang="en" dir="auto">

<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="robots" content="index, follow">
<title>Sliced Score Matching | WangJV Blog</title>
<meta name="keywords" content="unsupervised learning, 数据生成, 对比学习">
<meta name="description" content="1. 目的和动机
在之前的关于 Score Matching 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：
$$
\begin{aligned}  
J(\theta)
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla^2_\xi \log p(\xi, \theta)\right)&#43; \frac 1 2\left\| \nabla_\xi  \log p(\xi, \theta)\right\|^2
\right] \\
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)&#43; \frac 1 2\left\| \psi(\xi, \theta)\right \|^2
\right] \\
\end{aligned}
$$但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\nabla^2_\xi \log p(\xi, \theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：
$$
\frac{\partial}{\partial \theta} \big[ \text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)\big] = \text{tr} \left(\frac{\partial^2}{\partial \theta \xi}  \psi(\xi, \theta)\right)
$$这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：">
<meta name="author" content="WangJV">
<link rel="canonical" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/">
<link crossorigin="anonymous" href="https://wangjv0812.github.io/WangJV-Blog-Pages/assets/css/stylesheet.8fe10233a706bc87f2e08b3cf97b8bd4c0a80f10675a143675d59212121037c0.css" integrity="sha256-j&#43;ECM6cGvIfy4Is8&#43;XuL1MCoDxBnWhQ2ddWSEhIQN8A=" rel="preload stylesheet" as="style">
<link rel="icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://wangjv0812.github.io/WangJV-Blog-Pages/favicon-32x32.png">
<link rel="apple-touch-icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/apple-touch-icon.png">
<link rel="mask-icon" href="https://wangjv0812.github.io/WangJV-Blog-Pages/safari-pinned-tab.svg">
<meta name="theme-color" content="#2e2e33">
<meta name="msapplication-TileColor" content="#2e2e33">
<link rel="alternate" hreflang="en" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/">
<noscript>
    <style>
        #theme-toggle,
        .top-link {
            display: none;
        }

    </style>
    <style>
        @media (prefers-color-scheme: dark) {
            :root {
                --theme: rgb(29, 30, 32);
                --entry: rgb(46, 46, 51);
                --primary: rgb(218, 218, 219);
                --secondary: rgb(155, 156, 157);
                --tertiary: rgb(65, 66, 68);
                --content: rgb(196, 196, 197);
                --code-block-bg: rgb(46, 46, 51);
                --code-bg: rgb(55, 56, 62);
                --border: rgb(51, 51, 51);
            }

            .list {
                background: var(--theme);
            }

            .list:not(.dark)::-webkit-scrollbar-track {
                background: 0 0;
            }

            .list:not(.dark)::-webkit-scrollbar-thumb {
                border-color: var(--theme);
            }
        }

    </style>
</noscript><script>
  MathJax = {
    tex: {
      displayMath: [['\\[', '\\]'], ['$$', '$$']],
      inlineMath: [['\\(', '\\)'], ['$', '$']],
      processEscapes: true,
      processEnvironments: true,
      tags: 'ams'
    },
    chtml: {
      scale: 1,                     
      minScale: 0.5,               
      matchFontHeight: false,       
      displayAlign: 'center',       
      displayIndent: '0',           
      mtextInheritFont: false,      
      merrorInheritFont: true,      
      mathmlSpacing: false,         
      skipHtmlTags: ['script','noscript','style','textarea','pre','code','a'],
      ignoreHtmlClass: 'tex2jax_ignore',
      processHtmlClass: 'tex2jax_process'
    },
    svg: {
      scale: 1,                     
      minScale: 0.5,               
      mtextInheritFont: false,      
      merrorInheritFont: true,
      mathmlSpacing: false,
      skipHtmlTags: ['script','noscript','style','textarea','pre','code','a'],
      ignoreHtmlClass: 'tex2jax_ignore',
      processHtmlClass: 'tex2jax_process'
    },
    options: {
      enableMenu: true,             
      menuOptions: {
        settings: {
          zoom: 'Click'             
        }
      }
    },
    loader: {
      load: ['ui/safe', 'a11y/assistive-mml']
    },
    startup: {
      ready() {
        MathJax.startup.defaultReady();
        
        const observer = new ResizeObserver(entries => {
          MathJax.typesetPromise();
        });
        observer.observe(document.body);
      }
    }
  };
  
  
  if (window.innerWidth <= 768) {
    MathJax.chtml = MathJax.chtml || {};
    MathJax.chtml.scale = 0.9;  
  }
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>


<style>
   
  .MathJax {
    outline: 0;
  }
  
   
  @media (max-width: 768px) {
    .MathJax {
      font-size: 90% !important;
    }
    
     
    .MathJax_Display {
      overflow-x: auto;
      overflow-y: hidden;
      padding: 0 !important;
      margin: 1em 0 !important;
    }
    
     
    .MathJax_CHTML {
      line-height: 1.2 !important;
    }
  }
  
   
  mjx-container[jax="CHTML"][display="true"] {
    overflow-x: auto;
    overflow-y: hidden;
    padding: 1px 0;
  }
</style><meta property="og:url" content="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/">
  <meta property="og:site_name" content="WangJV Blog">
  <meta property="og:title" content="Sliced Score Matching">
  <meta property="og:description" content="1. 目的和动机 在之前的关于 Score Matching 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：
$$ \begin{aligned} J(\theta) &amp;= \text{E}_{\xi \sim p_X(\xi)}\left[ \text{tr} \left(\nabla^2_\xi \log p(\xi, \theta)\right)&#43; \frac 1 2\left\| \nabla_\xi \log p(\xi, \theta)\right\|^2 \right] \\ &amp;= \text{E}_{\xi \sim p_X(\xi)}\left[ \text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)&#43; \frac 1 2\left\| \psi(\xi, \theta)\right \|^2 \right] \\ \end{aligned} $$但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\nabla^2_\xi \log p(\xi, \theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：
$$ \frac{\partial}{\partial \theta} \big[ \text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)\big] = \text{tr} \left(\frac{\partial^2}{\partial \theta \xi} \psi(\xi, \theta)\right) $$这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：">
  <meta property="og:locale" content="en-us">
  <meta property="og:type" content="article">
    <meta property="article:section" content="posts">
    <meta property="article:published_time" content="2025-08-11T17:02:00+08:00">
    <meta property="article:modified_time" content="2025-08-11T17:02:00+08:00">
    <meta property="article:tag" content="Unsupervised Learning">
    <meta property="article:tag" content="数据生成">
    <meta property="article:tag" content="对比学习">
      <meta property="og:image" content="https://wangjv0812.github.io/WangJV-Blog-Pages/">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://wangjv0812.github.io/WangJV-Blog-Pages/">
<meta name="twitter:title" content="Sliced Score Matching">
<meta name="twitter:description" content="1. 目的和动机
在之前的关于 Score Matching 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：
$$
\begin{aligned}  
J(\theta)
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla^2_\xi \log p(\xi, \theta)\right)&#43; \frac 1 2\left\| \nabla_\xi  \log p(\xi, \theta)\right\|^2
\right] \\
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)&#43; \frac 1 2\left\| \psi(\xi, \theta)\right \|^2
\right] \\
\end{aligned}
$$但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\nabla^2_\xi \log p(\xi, \theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：
$$
\frac{\partial}{\partial \theta} \big[ \text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)\big] = \text{tr} \left(\frac{\partial^2}{\partial \theta \xi}  \psi(\xi, \theta)\right)
$$这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：">


<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position":  1 ,
      "name": "Posts",
      "item": "https://wangjv0812.github.io/WangJV-Blog-Pages/posts/"
    }, 
    {
      "@type": "ListItem",
      "position":  2 ,
      "name": "Sliced Score Matching",
      "item": "https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/"
    }
  ]
}
</script>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Sliced Score Matching",
  "name": "Sliced Score Matching",
  "description": "1. 目的和动机 在之前的关于 Score Matching 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：\n$$ \\begin{aligned} J(\\theta) \u0026= \\text{E}_{\\xi \\sim p_X(\\xi)}\\left[ \\text{tr} \\left(\\nabla^2_\\xi \\log p(\\xi, \\theta)\\right)+ \\frac 1 2\\left\\| \\nabla_\\xi \\log p(\\xi, \\theta)\\right\\|^2 \\right] \\\\ \u0026= \\text{E}_{\\xi \\sim p_X(\\xi)}\\left[ \\text{tr} \\left(\\nabla_\\xi \\psi(\\xi, \\theta)\\right)+ \\frac 1 2\\left\\| \\psi(\\xi, \\theta)\\right \\|^2 \\right] \\\\ \\end{aligned} $$但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\\nabla^2_\\xi \\log p(\\xi, \\theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：\n$$ \\frac{\\partial}{\\partial \\theta} \\big[ \\text{tr} \\left(\\nabla_\\xi \\psi(\\xi, \\theta)\\right)\\big] = \\text{tr} \\left(\\frac{\\partial^2}{\\partial \\theta \\xi} \\psi(\\xi, \\theta)\\right) $$这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：\n",
  "keywords": [
    "unsupervised learning", "数据生成", "对比学习"
  ],
  "articleBody": "1. 目的和动机 在之前的关于 Score Matching 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：\n$$ \\begin{aligned} J(\\theta) \u0026= \\text{E}_{\\xi \\sim p_X(\\xi)}\\left[ \\text{tr} \\left(\\nabla^2_\\xi \\log p(\\xi, \\theta)\\right)+ \\frac 1 2\\left\\| \\nabla_\\xi \\log p(\\xi, \\theta)\\right\\|^2 \\right] \\\\ \u0026= \\text{E}_{\\xi \\sim p_X(\\xi)}\\left[ \\text{tr} \\left(\\nabla_\\xi \\psi(\\xi, \\theta)\\right)+ \\frac 1 2\\left\\| \\psi(\\xi, \\theta)\\right \\|^2 \\right] \\\\ \\end{aligned} $$但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\\nabla^2_\\xi \\log p(\\xi, \\theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：\n$$ \\frac{\\partial}{\\partial \\theta} \\big[ \\text{tr} \\left(\\nabla_\\xi \\psi(\\xi, \\theta)\\right)\\big] = \\text{tr} \\left(\\frac{\\partial^2}{\\partial \\theta \\xi} \\psi(\\xi, \\theta)\\right) $$这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：\nSliced score matching Denoising score matching (DSM) 本文要讨论的则就是 Sliced Score Matching。\n2. Sliced Score Matching 受到 Sliced Wasserstein distance 的启发，宋飏博士提出 Sliced Score Matching 的方法。显然，处理一个 $1$ 维向量而非一个 $d$ 维向量容易非常多。那么如果我们将模型分布和真实分布 $p(\\theta, \\xi), p_X(\\xi)$ 的 score function. $\\psi(\\theta, \\xi), \\psi_X(\\xi)$ 随机的投影到一个随机变量 $v\\sim p_V(v)$ 上，去计算在投影向量上的平均 difference。那么，传统的 Score Matching 用的 fisher divergence 就变成了：\n$$ \\begin{aligned} J(\\theta, p(v)) = \\frac 1 2 \\mathbb{E}_{v\\sim p(v)} \\text{E}_{\\xi \\sim p_X(\\xi)}\\bigg[ \\left\\| \\psi(\\xi_i, \\theta) - \\psi_X(\\xi_i) \\right\\| ^2 \\bigg] \\end{aligned} $$之后的推导和 Score Matching 一直，只不过由于引入了随机向量 $v$，我们对 $v$ 增加了一些约束，这要求：\n$$ \\begin{array}{l} \\mathbb{E}_{v\\sim p(v)}\\left[vv^T\\right] \u003e 0\\\\ \\mathbb{E}_{v\\sim p(v)}\\left[\\| v \\|_2^2\\right] \u003c \\infty\\\\ \\end{array} $$事实上，这也是一个很弱的约束，大部分分布都满足。一般而言，$v$ 取标准高斯分布或者 Rademacher distribution 就好了。我们隐去具体的推导步骤（和 Score Matching 是一样的），此处给出结果\n$$ \\begin{aligned} J(\\theta, p(v)) \u0026= \\frac 1 2 \\mathbb{E}_{v\\sim p(v)}\\text{E}_{\\xi \\sim p_X(\\xi)}\\bigg[\\left\\| \\psi(\\xi_i, \\theta) - \\psi_X(\\xi_i) \\right\\| ^2\\bigg]\\\\ \u0026= \\mathbb{E}_{v\\sim p(v)}\\text{E}_{\\xi \\sim p_X(\\xi)}\\bigg[ v^T \\nabla_\\xi \\psi(\\xi, \\theta) v + \\frac 1 2\\left\\| v^T\\psi(\\xi, \\theta)\\right \\|^2 \\bigg]\\\\ \\end{aligned} $$对于数据集中的一个 $\\xi_i^N$，或者说对于真实分布 $p_x(\\xi)$ 的 $N$ 个采样中的一个。我们随机的在分布 $p(v)$ 中进行 $M$ 次抽样，其中任一个用于投影的随机向量 $v_{ij}^{NM}$。那么对应的估计可以写作：\n$$ \\hat{J}(\\theta, x_i^N, v_{ij}^{NM}) = \\frac 1 N \\frac 1 M \\sum_{i=1}^{N} \\sum_{j=1}^{M} v_{ij}^T \\nabla_\\xi \\psi(\\xi_i, \\theta) v_{ij} + \\frac 1 2\\left\\| v_{ij}^T\\psi(\\xi_i, \\theta) \\right \\|^2 $$注意力集中！不难注意到，由于 $v$ 服从高斯分布或者 Rademacher distribution，有（推导见附录）：\n$$ \\mathbb{E}_{p(v)} \\left[\\left(v^T \\psi(\\xi_i, \\theta)\\right)^2\\right] = \\left\\|\\psi(\\xi_i, \\theta)\\right\\|^2_2 $$那么，上式可以简化为：\n$$ \\hat{J}_{vr}(\\theta, x_i^N, v_{ij}^{NM}) = \\frac 1 N \\frac 1 M \\sum_{i=1}^{N} \\sum_{j=1}^{M} v_{ij}^T \\nabla_\\xi \\psi(\\xi_i, \\theta) v_{ij} + \\frac 1 2 \\left\\|\\psi(\\xi_i, \\theta)\\right\\|^2_2 $$事实上，我们在 Score Matching 中，已经 “剧透” 了这部分内容。$v_{ij}^T \\nabla_\\xi \\psi(\\xi_i, \\theta) v_{ij}$ 就是上一篇文章中介绍的 Hessain Trace Estimation。显然的，$\\hat{J}_{vr}$ 的表现是优于 $\\hat{J}$（不只是在计算复杂度上，还在估计的效果上）。由于我们通过解析的方法事实上消除了 $\\left\\| \\psi(\\xi, \\theta)\\right \\|^2$ 的随机性，这在事实上移除了一个对结果方差的 “贡献源”，有效的降低了结果的方差。\n关于 $v_{ij}^T \\nabla_\\xi \\psi(\\xi_i, \\theta) v_{ij}$ 的估计，我们在上一篇文章中已经介绍了。具体参考 Score Matching 4.1. 哈钦森迹估计。之前在计算 $\\text{tr} \\left(\\nabla_\\xi \\psi(\\xi, \\theta)\\right)$ 时，需要进行 $d$ 次反向传播，而对于一次 $v_i$，$v_{ij}^T \\nabla_\\xi \\psi(\\xi_i, \\theta) v_{ij}$ 只需要进行一次反向传播。而一般而言，$M \u003c\u003c d$，极大的降低了算法的复杂度。\n在实践中，分布 $p(v)$ 的采样次数 $M$ 可以用于平衡计算复杂度和估计的方差。有趣的是 YangSong 的论文中指出，甚至 $M = 1$ 也是一个不错的选择。\nAppendix ",
  "wordCount" : "355",
  "inLanguage": "en",
  "image": "https://wangjv0812.github.io/WangJV-Blog-Pages/","datePublished": "2025-08-11T17:02:00+08:00",
  "dateModified": "2025-08-11T17:02:00+08:00",
  "author":{
    "@type": "Person",
    "name": "WangJV"
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/sliced-score-matching/"
  },
  "publisher": {
    "@type": "Organization",
    "name": "WangJV Blog",
    "logo": {
      "@type": "ImageObject",
      "url": "https://wangjv0812.github.io/WangJV-Blog-Pages/favicon.ico"
    }
  }
}
</script>
</head>

<body class="" id="top">
<script>
    if (localStorage.getItem("pref-theme") === "dark") {
        document.body.classList.add('dark');
    } else if (localStorage.getItem("pref-theme") === "light") {
        document.body.classList.remove('dark')
    } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
        document.body.classList.add('dark');
    }

</script>

<header class="header">
    <nav class="nav">
        <div class="logo">
            <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/" accesskey="h" title="WangJV Blog (Alt + H)">WangJV Blog</a>
            <div class="logo-switches">
                <button id="theme-toggle" accesskey="t" title="(Alt + T)" aria-label="Toggle theme">
                    <svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                        fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                        stroke-linejoin="round">
                        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
                    </svg>
                    <svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
                        fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
                        stroke-linejoin="round">
                        <circle cx="12" cy="12" r="5"></circle>
                        <line x1="12" y1="1" x2="12" y2="3"></line>
                        <line x1="12" y1="21" x2="12" y2="23"></line>
                        <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
                        <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
                        <line x1="1" y1="12" x2="3" y2="12"></line>
                        <line x1="21" y1="12" x2="23" y2="12"></line>
                        <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
                        <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
                    </svg>
                </button>
            </div>
        </div>
        <ul id="menu">
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/" title="Home">
                    <span>Home</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/posts/" title="Posts">
                    <span>Posts</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/archives/" title="Archive">
                    <span>Archive</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/" title="Tags">
                    <span>Tags</span>
                </a>
            </li>
            <li>
                <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/search/" title="🔍 Search (Alt &#43; /)" accesskey=/>
                    <span>🔍 Search</span>
                </a>
            </li>
        </ul>
    </nav>
</header>
<main class="main">

<article class="post-single">
  <header class="post-header">
    <div class="breadcrumbs"><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/">Home</a>&nbsp;»&nbsp;<a href="https://wangjv0812.github.io/WangJV-Blog-Pages/posts/">Posts</a></div>
    <h1 class="post-title entry-hint-parent">
      Sliced Score Matching
    </h1>
    <div class="post-meta"><span title='2025-08-11 17:02:00 +0800 CST'>August 11, 2025</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;355 words&nbsp;·&nbsp;WangJV&nbsp;|&nbsp;<a href="https://github.com/WangJV0812/WangJV-Blog-Source/tree/master/content/posts/Sliced%20Score%20Matching/inedx.md" rel="noopener noreferrer edit" target="_blank">Suggest Changes</a>

</div>
  </header> <div class="toc">
    <details >
        <summary accesskey="c" title="(Alt + C)">
            <span class="details">Table of Contents</span>
        </summary>

        <div class="inner"><nav id="TableOfContents">
  <ul>
    <li><a href="#1-目的和动机">1. 目的和动机</a></li>
    <li><a href="#2-sliced-score-matching">2. Sliced Score Matching</a></li>
    <li><a href="#appendix">Appendix</a></li>
  </ul>
</nav>
        </div>
    </details>
</div>

  <div class="post-content"><h2 id="1-目的和动机">1. 目的和动机<a hidden class="anchor" aria-hidden="true" href="#1-目的和动机">#</a></h2>
<p>在之前的关于 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/scorematching/">Score Matching</a> 的文章中，介绍了 Score Matching 的基本概念和方法。Score Matching 巧妙的引入了 Score Function，避免了直接计算高维随机向量的归一化系数，让估计一个高维分布成为了可能。其 Loss Function 可以写作：</p>
$$
\begin{aligned}  
J(\theta)
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla^2_\xi \log p(\xi, \theta)\right)+ \frac 1 2\left\| \nabla_\xi  \log p(\xi, \theta)\right\|^2
\right] \\
&= \text{E}_{\xi \sim p_X(\xi)}\left[
\text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)+ \frac 1 2\left\| \psi(\xi, \theta)\right \|^2
\right] \\
\end{aligned}
$$<p>但是成为可能不代表它好算。Score Matching 引入了对原始分布的 Hessian Matrix 的迹 $\nabla^2_\xi \log p(\xi, \theta)$ 的计算。显然，这比直接计算归一化系数简单了不少，但是对于一个维度为 $d$ 的随机向量的估计，需要进行 $d$ 次反向传播，者仍然十分困难。更可怕的是，在反向传播的过程中需要计算：</p>
$$
\frac{\partial}{\partial \theta} \big[ \text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)\big] = \text{tr} \left(\frac{\partial^2}{\partial \theta \xi}  \psi(\xi, \theta)\right)
$$<p>这一项对于数值计算而言就是灾难。在实践中，需要找到一个真实可行的简化方法。人们常常使用的方法有：</p>
<ol>
<li>Sliced score matching</li>
<li>Denoising score matching (DSM)</li>
</ol>
<p>本文要讨论的则就是 Sliced Score Matching。</p>
<h2 id="2-sliced-score-matching">2. Sliced Score Matching<a hidden class="anchor" aria-hidden="true" href="#2-sliced-score-matching">#</a></h2>
<p>受到 Sliced Wasserstein distance 的启发，宋飏博士提出 Sliced Score Matching 的方法。显然，处理一个 $1$ 维向量而非一个 $d$ 维向量容易非常多。那么如果我们将模型分布和真实分布 $p(\theta, \xi), p_X(\xi)$ 的 score function. $\psi(\theta, \xi), \psi_X(\xi)$ 随机的投影到一个随机变量 $v\sim p_V(v)$ 上，去计算在投影向量上的平均 difference。那么，传统的 Score Matching 用的 fisher divergence 就变成了：</p>
$$
\begin{aligned}
J(\theta, p(v))
= \frac 1 2 \mathbb{E}_{v\sim p(v)}
\text{E}_{\xi \sim p_X(\xi)}\bigg[
\left\|
\psi(\xi_i, \theta) - \psi_X(\xi_i)
\right\| ^2
\bigg]
\end{aligned}
$$<p>之后的推导和 Score Matching 一直，只不过由于引入了随机向量 $v$，我们对 $v$ 增加了一些约束，这要求：</p>
$$
\begin{array}{l}
\mathbb{E}_{v\sim p(v)}\left[vv^T\right] > 0\\
\mathbb{E}_{v\sim p(v)}\left[\| v \|_2^2\right] < \infty\\
\end{array}
$$<p>事实上，这也是一个很弱的约束，大部分分布都满足。一般而言，$v$ 取标准高斯分布或者 Rademacher distribution 就好了。我们隐去具体的推导步骤（和 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/scorematching/">Score Matching</a> 是一样的），此处给出结果</p>
$$
\begin{aligned}
J(\theta, p(v))
&= \frac 1 2 \mathbb{E}_{v\sim p(v)}\text{E}_{\xi \sim p_X(\xi)}\bigg[\left\|
\psi(\xi_i, \theta) - \psi_X(\xi_i)
\right\| ^2\bigg]\\
&= \mathbb{E}_{v\sim p(v)}\text{E}_{\xi \sim p_X(\xi)}\bigg[
v^T \nabla_\xi \psi(\xi, \theta) v + \frac 1 2\left\| v^T\psi(\xi, \theta)\right \|^2
\bigg]\\
\end{aligned}
$$<p>对于数据集中的一个 $\xi_i^N$，或者说对于真实分布 $p_x(\xi)$ 的 $N$ 个采样中的一个。我们随机的在分布 $p(v)$ 中进行 $M$ 次抽样，其中任一个用于投影的随机向量 $v_{ij}^{NM}$。那么对应的估计可以写作：</p>
$$
\hat{J}(\theta, x_i^N, v_{ij}^{NM}) = \frac 1 N \frac 1 M \sum_{i=1}^{N} \sum_{j=1}^{M}
v_{ij}^T \nabla_\xi \psi(\xi_i, \theta) v_{ij} + \frac 1 2\left\| v_{ij}^T\psi(\xi_i, \theta)
\right \|^2
$$<p>注意力集中！不难注意到，由于 $v$ 服从高斯分布或者 Rademacher distribution，有（推导见附录）：</p>
$$
\mathbb{E}_{p(v)} \left[\left(v^T \psi(\xi_i, \theta)\right)^2\right] = \left\|\psi(\xi_i, \theta)\right\|^2_2
$$<p>那么，上式可以简化为：</p>
$$
\hat{J}_{vr}(\theta, x_i^N, v_{ij}^{NM}) = \frac 1 N \frac 1 M \sum_{i=1}^{N} \sum_{j=1}^{M}
v_{ij}^T \nabla_\xi \psi(\xi_i, \theta) v_{ij} + \frac 1 2 \left\|\psi(\xi_i, \theta)\right\|^2_2
$$<p>事实上，我们在 Score Matching 中，已经 “剧透” 了这部分内容。$v_{ij}^T \nabla_\xi \psi(\xi_i, \theta) v_{ij}$ 就是上一篇文章中介绍的 Hessain Trace Estimation。显然的，$\hat{J}_{vr}$ 的表现是优于 $\hat{J}$（不只是在计算复杂度上，还在估计的效果上）。由于我们通过解析的方法事实上消除了 $\left\| \psi(\xi, \theta)\right \|^2$ 的随机性，这在事实上移除了一个对结果方差的 “贡献源”，有效的降低了结果的方差。</p>
<p>关于 $v_{ij}^T \nabla_\xi \psi(\xi_i, \theta) v_{ij}$ 的估计，我们在上一篇文章中已经介绍了。具体参考 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/scorematching/#41-%E5%93%88%E9%92%A6%E6%A3%AE%E8%BF%B9%E4%BC%B0%E8%AE%A1-hutchinsons-trace-estimation">Score Matching 4.1. 哈钦森迹估计</a>。之前在计算 $\text{tr} \left(\nabla_\xi \psi(\xi, \theta)\right)$ 时，需要进行 $d$ 次反向传播，而对于一次 $v_i$，$v_{ij}^T \nabla_\xi \psi(\xi_i, \theta) v_{ij}$ 只需要进行一次反向传播。而一般而言，$M << d$，极大的降低了算法的复杂度。</p>
<p>在实践中，分布 $p(v)$ 的采样次数 $M$ 可以用于平衡计算复杂度和估计的方差。有趣的是 YangSong 的论文中指出，甚至 $M = 1$ 也是一个不错的选择。</p>
<h2 id="appendix">Appendix<a hidden class="anchor" aria-hidden="true" href="#appendix">#</a></h2>


  </div>

  <footer class="post-footer">
    <ul class="post-tags">
      <li><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/unsupervised-learning/">Unsupervised Learning</a></li>
      <li><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/%E6%95%B0%E6%8D%AE%E7%94%9F%E6%88%90/">数据生成</a></li>
      <li><a href="https://wangjv0812.github.io/WangJV-Blog-Pages/tags/%E5%AF%B9%E6%AF%94%E5%AD%A6%E4%B9%A0/">对比学习</a></li>
    </ul>
<nav class="paginav">
  <a class="prev" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/noise-contrastive-estimation/">
    <span class="title">« Prev</span>
    <br>
    <span>Noise Contrastive Estimation</span>
  </a>
  <a class="next" href="https://wangjv0812.github.io/WangJV-Blog-Pages/2025/08/scorematching/">
    <span class="title">Next »</span>
    <br>
    <span>ScoreMatching</span>
  </a>
</nav>

  </footer>
</article>
    </main>
    
<footer class="footer">
        <span>&copy; 2025 <a href="https://wangjv0812.github.io/WangJV-Blog-Pages/">WangJV Blog</a></span> · 

    <span>
        Powered by
        <a href="https://gohugo.io/" rel="noopener noreferrer" target="_blank">Hugo</a> &
        <a href="https://github.com/adityatelange/hugo-PaperMod/" rel="noopener" target="_blank">PaperMod</a>
    </span>
</footer>
<a href="#top" aria-label="go to top" title="Go to Top (Alt + G)" class="top-link" id="top-link" accesskey="g">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentColor">
        <path d="M12 6H0l6-6z" />
    </svg>
</a>

<script>
    let menu = document.getElementById('menu')
    if (menu) {
        menu.scrollLeft = localStorage.getItem("menu-scroll-position");
        menu.onscroll = function () {
            localStorage.setItem("menu-scroll-position", menu.scrollLeft);
        }
    }

    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener("click", function (e) {
            e.preventDefault();
            var id = this.getAttribute("href").substr(1);
            if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
                document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView({
                    behavior: "smooth"
                });
            } else {
                document.querySelector(`[id='${decodeURIComponent(id)}']`).scrollIntoView();
            }
            if (id === "top") {
                history.replaceState(null, null, " ");
            } else {
                history.pushState(null, null, `#${id}`);
            }
        });
    });

</script>
<script>
    var mybutton = document.getElementById("top-link");
    window.onscroll = function () {
        if (document.body.scrollTop > 800 || document.documentElement.scrollTop > 800) {
            mybutton.style.visibility = "visible";
            mybutton.style.opacity = "1";
        } else {
            mybutton.style.visibility = "hidden";
            mybutton.style.opacity = "0";
        }
    };

</script>
<script>
    document.getElementById("theme-toggle").addEventListener("click", () => {
        if (document.body.className.includes("dark")) {
            document.body.classList.remove('dark');
            localStorage.setItem("pref-theme", 'light');
        } else {
            document.body.classList.add('dark');
            localStorage.setItem("pref-theme", 'dark');
        }
    })

</script>
<script>
    document.querySelectorAll('pre > code').forEach((codeblock) => {
        const container = codeblock.parentNode.parentNode;

        const copybutton = document.createElement('button');
        copybutton.classList.add('copy-code');
        copybutton.innerHTML = 'copy';

        function copyingDone() {
            copybutton.innerHTML = 'copied!';
            setTimeout(() => {
                copybutton.innerHTML = 'copy';
            }, 2000);
        }

        copybutton.addEventListener('click', (cb) => {
            if ('clipboard' in navigator) {
                navigator.clipboard.writeText(codeblock.textContent);
                copyingDone();
                return;
            }

            const range = document.createRange();
            range.selectNodeContents(codeblock);
            const selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(range);
            try {
                document.execCommand('copy');
                copyingDone();
            } catch (e) { };
            selection.removeRange(range);
        });

        if (container.classList.contains("highlight")) {
            container.appendChild(copybutton);
        } else if (container.parentNode.firstChild == container) {
            
        } else if (codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName == "TABLE") {
            
            codeblock.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(copybutton);
        } else {
            
            codeblock.parentNode.appendChild(copybutton);
        }
    });
</script>
</body>

</html>
